package com.changan.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.changan.dto.UserExcelDTO;
import com.changan.entity.User;
import com.changan.exception.BusinessException;
import com.changan.mapper.UserMapper;
import com.changan.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changan.utils.JWTUtils;
import com.changan.utils.MD5Utils;
import com.changan.vo.LoginVO;
import com.changan.vo.UserAddVO;
import com.changan.vo.UserQueryVO;
import com.changan.vo.UserUpdateVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author NieChangan
 * @since 2025-09-03
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public String login(LoginVO loginVO) {
        // 根据电话号码获取到用户名
        User user = this.baseMapper.selectOne(new QueryWrapper<User>().eq("phone_number", loginVO.getPhoneNumber()));
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        // 拿到盐值和名文密码
        String salt = user.getSalt();
        String password = MD5Utils.md5Encryption(loginVO.getPassword(), salt);
        if (!user.getPassword().equals(password)) {
            throw new BusinessException(500, "密码错误");
        }
        // 生成token
        String token = JWTUtils.sign(user.getUsername(), user.getPassword());
        return token;
    }

    @Override
    public User add(UserAddVO userAddVO) {
        User user = new User();
        BeanUtils.copyProperties(userAddVO, user);
        String salt = UUID.randomUUID().toString().substring(0, 32);
        user.setSalt(salt);
        user.setPassword(MD5Utils.md5Encryption(userAddVO.getPassword(), salt));
        this.save(user);
        return user;
    }

    @Override
    public User getUserById(Long id) {
        return getById(id);
    }

    @Override
    public Page<User> users(UserQueryVO userQueryVO) {
        Page<User> page = new Page<>(userQueryVO.getPageNum(), userQueryVO.getPageSize());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(userQueryVO.getUsername()), User::getUsername, userQueryVO.getUsername());
        queryWrapper.like(StrUtil.isNotBlank(userQueryVO.getNickname()), User::getNickname, userQueryVO.getNickname());
        queryWrapper.like(StrUtil.isNotBlank(userQueryVO.getEmail()), User::getEmail, userQueryVO.getEmail());
        queryWrapper.like(StrUtil.isNotBlank(userQueryVO.getPhoneNumber()), User::getPhoneNumber, userQueryVO.getPhoneNumber());
        queryWrapper.eq(userQueryVO.getStatus() != null, User::getStatus, userQueryVO.getStatus());
        queryWrapper.eq(userQueryVO.getSex() != null, User::getSex, userQueryVO.getSex());
        queryWrapper.orderByDesc(User::getCreateTime);
        return this.page(page, queryWrapper);
    }

    @Override
    public User modify(UserUpdateVO userUpdateVO) {
        // 1. 获取用户
        User user = this.getById(userUpdateVO.getId());
        BeanUtils.copyProperties(userUpdateVO, user);
        user.setPassword(MD5Utils.md5Encryption(userUpdateVO.getPassword(), user.getSalt()));
        this.updateById(user);
        return user;
    }

    @Override
    public Boolean delete(Long id) {
        return this.removeById(id);
    }

    @Override
    public Boolean status(Long id, Integer status) {
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id)
                .set(User::getStatus, status);
        return this.update(updateWrapper);
    }

    /**
     * 实现：查询导出用的用户列表
     */
    @Override
    public List<UserExcelDTO> listExportUsers(UserQueryVO queryVO) {
        // 1. 构建查询条件（MyBatis-Plus LambdaQueryWrapper，避免SQL注入）
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 1.1 用户名：模糊查询（若参数不为空）
        if (queryVO.getUsername() != null && !queryVO.getUsername().trim().isEmpty()) {
            queryWrapper.like(User::getUsername, queryVO.getUsername().trim());
        }

        // 1.2 昵称：模糊查询（若参数不为空）
        if (queryVO.getNickname() != null && !queryVO.getNickname().trim().isEmpty()) {
            queryWrapper.like(User::getNickname, queryVO.getNickname().trim());
        }

        // 1.3 邮箱：模糊查询（若参数不为空）
        if (queryVO.getEmail() != null && !queryVO.getEmail().trim().isEmpty()) {
            queryWrapper.like(User::getEmail, queryVO.getEmail().trim());
        }

        // 1.4 联系电话：模糊查询（若参数不为空）
        if (queryVO.getPhoneNumber() != null && !queryVO.getPhoneNumber().trim().isEmpty()) {
            queryWrapper.like(User::getPhoneNumber, queryVO.getPhoneNumber().trim());
        }

        // 1.5 状态：精确查询（若参数不为空，0=禁用，1=启用）
        if (queryVO.getStatus() != null) {
            queryWrapper.eq(User::getStatus, queryVO.getStatus());
        }

        // 1.6 性别：精确查询（若参数不为空，0=男，1=女，2=保密）
        if (queryVO.getSex() != null) {
            queryWrapper.eq(User::getSex, queryVO.getSex());
        }

        // 1.7 排序：按创建时间降序（与前端列表排序一致）
        queryWrapper.orderByDesc(User::getCreateTime);

        // 2. 数据库查询：获取符合条件的User列表（全量，无分页）
        List<User> userList = this.baseMapper.selectList(queryWrapper);

        // 3. 转换：将数据库实体User → 导出DTO UserExcelDTO（用Stream流简化转换）
        return userList.stream().map(user -> {
            UserExcelDTO excelDTO = new UserExcelDTO();
            // 3.1 复制相同字段（如id、username、nickname等，需保证字段名和类型一致）
            BeanUtils.copyProperties(user, excelDTO);
            // 3.2 特殊字段处理（若有差异，如日期格式、自定义字段等，此处无差异可忽略）
            // 例：若User的birth是String类型，需转为Date：excelDTO.setBirth(new SimpleDateFormat("yyyy-MM-dd").parse(user.getBirth()));
            return excelDTO;
        }).collect(Collectors.toList());

        /*List<UserExcelDTO> userExcelDTOList = new ArrayList<>();
        for (User user : userList) {
            UserExcelDTO userExcelDTO = new UserExcelDTO();
            BeanUtils.copyProperties(user, userExcelDTO);
            userExcelDTOList.add(userExcelDTO);
        }
        return userExcelDTOList;*/
    }

    @Override
    public String test() {
        /*Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("执行定时任务");
            }
        },1000,1000);*/

        Runnable runnable = new Runnable() {
            public void run() {
                System.out.println("ScheduledExecutorService Task is called!");
            }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 参数：1、任务体 2、首次执行的延时时间
        //      3、任务执行间隔 4、间隔时间单位
        service.scheduleAtFixedRate(runnable, 0, 3, TimeUnit.SECONDS);

        return "success";
    }
}
